Projet Zuul de conception orientée objet en Java d'un jeu d'aventure
Forum des exercices du projet Zuul
Exercice 7.44
Add a beamer to the game. A beamer is a device that can be charged, and
fired. When you charge the beamer, it memorizes the current room. When
you fire the beamer, it transports you immediately back to the room it
was charged in.
The beamer could either be standard equipment, or an item that the player can find.
Of course, you need commands to charge and fire the beamer.
Le téléporteur (beamer) est un Item qui doit pouvoir être ramassé
dans une première pièce, peut ensuite être chargé dans une deuxième
pièce, puis déclenché dans une troisième.
Il peut éventuellement être réutilisable, mais dans ce cas, il doit obligatoirement être rechargé.
Questions à se poser pour faire les bons choix d'implémentation :
- et s'il y avait plusieurs téléporteurs ?
- et s'il y avait plusieurs joueurs ?
Ne pas oublier de lire les échanges ci-dessous pour mieux comprendre la bonne manière de réaliser cet exercice.
Doit on respecter la consigne en anglais "When you fire the beamer, it transports you immediately back to the room it was charged in." ou rentrer le choix d'une pièce en particulier?
Doit-on rajouter les commandes USE("use") et CHARGE("charge") juste pour le beamer ?
Le beamer rend selon moi les trap door inutilisable.
Nous avons dans notre jeu plusieurs époques et avons donc utilisé des trap doors pour éviter de revenir dans des époques.
Or
si on charge le beamer dans une époque et l'utillisont dans une autre
époque, le fait de réaliser des trap doors ne sert plus à rien.
Doit-on réinilialisé aussi le beamer sinon à chaque époque ?
En réalité je ne vois pas en quel circonstance nous allons pouvoir utilisé le beamer dans notre jeu.
Un étudiant a écrit :
Je ne comprends vraiment pas pourquoi on dervait créer une classe Beamer?
Mais ne peut-on pas mettre ces attributs dans le joueur, puisqu'ils le concernent aussi, au final?
Reconsidérez la question à la lumière de cet exemple :
Un joueur A charge un Beamer dans une pièce, le dépose dans la cuisine, puis s'en va.
Un joueur B arrive dans la cuisine, ramasse le Beamer et le déclenche.
Où devrait être stockée la pièce vers laquelle le joueur B va être transporté ?
Bonjour. Bien qu'il faut créer une classe Beamer, dans notre interpretCommand de GameEngine, lorsque qu'on devra appeler la méthode "charge" de la classe Beamer (par exemple), le seul attribut qui me semble utilisable(dans GameEngine) est aPlayer... Donc j'ai l'impression qu'il faudra toujours passer par la classe Player pour pouvoir appeler "charge" ou"fire" ... Peut-on le faire ?
Il faut effectivement passer par le Player pour récupérer la liste des Items qu'il porte, dont le Beamer.
Ensuite, c'est bien au Beamer qu'on s'adresse pour y charger la pièce ou pour récupérer celle qui y est déjà chargée.
L'étudiant a répondu :
D'accord merci !
Une dernière question : pour fire par exemple, lorsqu'on regarde si le beamer contient une Room "chargée", on peut le faire dans Beamer. Mais pour afficher un message d'erreur c'est dans la classe Player que cela se fait le plus facilement !
Ma question : regarder si le beamer contient une room,tout cela dans la classe Player, pose t-il probleme?
Bonsoir, après avoir été téléporté dans une Room, si on fait back, que devrait-il se passer ?
bonsoir
je viens d'implementer le beameur à mon programme.
plutot
que de creer une classe beamer qui herite de la classe Items , j'ai
choisi de simplement creer une attribut aBeamerRoom dans la classe
Player .
.Certe il me faut un atribut pour chaque beamer si je decide d'en rajouter , mais un jeu avec ne serait-ce que deux beamer est bien trop compliqué(d'un point de vu mecanique de jeu)
Suite à un pb technique, je viens seulement d'être prévenu de votre message.
Oui, c'est "mal", car le but est de vous apprendre la "bonne conception" d'un programme.
C'est pour cela qu'il faut imaginer qu'il y ait 2 players et 2 beamers pour choisir la bonne structuration du code, même s'il n'y a qu'un Player et qu'un Beamer dans votre jeu.
Même s'il n'y avait qu'un Beamer, que se passe-t-il si le
Player1 le charge dans une pièce, le dépose dans une autre pièce, et
qu'il est ramassé par le Player2 qui veut le déclencher ? Vous devez en
déduire que stocker la "pièce mémorisée" dans le Player
n'est clairement pas une bonne solution.
Un étudiant a écrit :
Bonjour
j'ai une erreur que je n'arrive pas à résoudre.
Bien que vous ne le disiez pas explicitement, je suppose que la NullPointerException survient à cette ligne :
this.aItemList.put( pItem.getDescriptionItem(), pItem );
Dans ce cas, il n'y a que 3 possibilités :
1) this.aItemList vaut null
2) pItem vaut null
3) pItem.getDescriptionItem() retourne null
De simples System.out.println vous donneront la réponse ...
Ensuite, il ne vous restera qu'à chercher l'instruction qui selon vous aurait dû faire en sorte que ce ne soit pas null, et vous vous apercevrez probablement de votre erreur.
1) Je ne comprends pas à quoi sert votre attribut aBeamer.
2) Mémorisez this.aPlayer.getItemList().getItem("MemoryAlpha") dans une variable de type Item.
3) Pourquoi les appels de méthodes ne marchent pas ?
La réponse
est dans l'éternelle différence entre type déclaré (utilisé à la
compilation) et type constaté (utilisé à l'exécution).
Votre variable est déclarée de type Item, donc le compilateur ne peut pas appeler une méthode de Beamer dessus, même si VOUS savez qu'à l'exécution, cet Item sera effectivement de type constaté Beamer.
Il vous faut donc convertir cette référence d'Item en référence de Beamer (ce qui est toujours autorisé par le compilateur car Beamer hérite d'Item et ce qui ne posera pas de problème à l'exécution puisque VOUS savez que c'est bien un Beamer) pour pouvoir
appeler les méthodes de Beamer.
Bonjour,
Après avoir implémenté les commandes charge et fire et tout ce qui va avec, je me retrouve confronté au problème suivant :
Beamer est une sous-classe de Item (extends), et chaque Room (et chaque Player aussi d'ailleurs) contient une ItemList d'Item, ce qui fait qu'en ajoutant un Beamer au sol dans mon jeu, lorsque je veux tester mon jeu en ramassant ce Beamer, puis en le chargeant (etc ...), le Beamer ne peut pas se charger car c'est devenu un Item à la place d'un Beamer : le Beamer a été converti en Item.
Comment m'y prendre pour remédier à ce problème ?
Si vous vérifiez que votre Item est bien une instance de Beamer (on a vu un opérateur pour cela à la fin du cours 6), vous avez le droit de convertir cet Item en Beamer.
Bonsoir,
Dans cet exercice, j'ai voulu mettre plusieurs objet Beamer dans mon jeu.
Du coup, lors de charge or fire, je dois vérifier si l'objet que met l'utilisateur est bien un beamer.
(Je ne peux donc pas directement mettre :
Beamer vBeamer = (Beamer)this.aPlayer.getBag().getItem(ItemName);
)
Du coup j'ai pensé à faire une vérification avant l'affectation, avec une comparaison de getClass() :
Beamer vBeamer= new Beamer("Trash",0,0,false,0,false);
if(this.aPlayer.getBag().getItem(ItemName).getClass()!=vBeamer.getClass())
Cependant, lors des tests, cela ne correspond pas.
Je suppose donc que vu que getItem() renvoie un Item, l'ordinateur considère ça comme un Item...
En
excluant la solution où j'ajoute à la classe Item un attribut boolean
aIsBeamer, je ne vois donc pas comment vérifier que un item est bien un
beamer.
Il y aurait-t-il un moyen de vérifier si un objet est un beamer, sans ajouter un attribut ?
Et dans le cas contraire, est-ce de la mal programmation ?
Merci,
et Bonne soirée à vous.
Cordialement,
Eddy Ly
- "Je suppose donc que vu que getItem() renvoie un Item, l'ordinateur considère ça comme un Item..."
Non, getClass() retourne bien le type constaté, donc un Beamer si c'en est un.
- "if ( this.aPlayer.getBag().getItem(ItemName).getClass() != vBeamer.getClass() )"
Ce code devrait fonctionner si Beamer hérite d' Item et si itemName est bien le nom d'un objet de type Beamer.
- Est-ce bien la différence que vous voulez tester, et non pas l'égalité ?
Un étudiant a écrit :
Est-ce une bonne idée d'essayer de faire en sorte que les mots charge et
fire n' apparaissent dans validCommands[] qu'une fois le beamer
récupéré?
C'est une idée astucieuse, mais bidouilleuse.
Et vous avez une méthode pour modifier la description de n'importe quelle pièce ?
Je
ne compte pas modifier la description de la salle mais celle du nouveau
Beamer indiquant ainsi la pièce ou il pourrait téléporter à l'aide d'un
substring ne prenant en compte que la description de la pièce, je
compare celle ci au description du aMap de GameEngine afin d'avoir la
pièce que j'utilise de la même manière que mon go room
Pardon, je voulais dire que vous avez une méthode qui permet de modifier la description de n'importe quel Item, ce qui n'est pas trop dans l'esprit de ce projet.
Il faut que vous compreniez que ce genre de solution n'est pas "propre". Elle dépend trop de l'écriture exacte des String manipulées, à la virgule et à la majuscule près, et elle "cache" la fonctionnalité quand on lit le code.
De façon générale quand on veut ajouter une fonctionnalité, on ajoute clairement un attribut, et/ou une méthode, et/ou une classe.
Ici, le Beamer étant une sorte d'Item qui doit
mémoriser une information supplémentaire (la Room) et doit fournir deux
services supplémentaires (charger et déclencher), cela se prête bien à
cette organisation du code.
Bonjour,
Est-ce que je peux utiliser une unique commande use qui, utilisée deux fois.
1) use beamer : permet de charger le beamer
2) use beamer : permet de tirer le beamer.
Cela permet de ne pas introduire des commandes inutiles qui ne serviront jamais.
Un étudiant a écrit :
Que ce soit le même joueur ou un autre joueur qui cherche à recharger le Beamer, l'énoncé ne dit pas ce qu'il faut faire.
Vous pouvez donc choisir de l'autoriser ou de l'interdire (avec un message informatif, bien sûr).
Réseaux sociaux